﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Poly2Tri
{
	// Token: 0x020003F5 RID: 1013
	public class Polygon : Point2DList, ITriangulatable, IEnumerable<TriangulationPoint>, IList<TriangulationPoint>, IEnumerable, ICollection<TriangulationPoint>
	{
		// Token: 0x06001BE2 RID: 7138 RVA: 0x000AF930 File Offset: 0x000ADB30
		public Polygon(IList<PolygonPoint> points)
		{
			if (points.Count < 3)
			{
				throw new ArgumentException("List has fewer than 3 points", "points");
			}
			this.AddRange(points, Point2DList.WindingOrderType.Unknown);
		}

		// Token: 0x06001BE3 RID: 7139 RVA: 0x000AF97D File Offset: 0x000ADB7D
		public Polygon(IEnumerable<PolygonPoint> points) : this((points as IList<PolygonPoint>) ?? points.ToArray<PolygonPoint>())
		{
		}

		// Token: 0x06001BE4 RID: 7140 RVA: 0x000AF998 File Offset: 0x000ADB98
		public Polygon(params PolygonPoint[] points) : this(points)
		{
		}

		// Token: 0x170003E8 RID: 1000
		// (get) Token: 0x06001BE5 RID: 7141 RVA: 0x000AF9A1 File Offset: 0x000ADBA1
		public IList<TriangulationPoint> Points
		{
			get
			{
				return this;
			}
		}

		// Token: 0x170003E9 RID: 1001
		// (get) Token: 0x06001BE6 RID: 7142 RVA: 0x000AF9A4 File Offset: 0x000ADBA4
		public IList<DelaunayTriangle> Triangles
		{
			get
			{
				return this.mTriangles;
			}
		}

		// Token: 0x170003EA RID: 1002
		// (get) Token: 0x06001BE7 RID: 7143 RVA: 0x00070CF8 File Offset: 0x0006EEF8
		public TriangulationMode TriangulationMode
		{
			get
			{
				return TriangulationMode.Polygon;
			}
		}

		// Token: 0x170003EB RID: 1003
		// (get) Token: 0x06001BE8 RID: 7144 RVA: 0x000AF9AC File Offset: 0x000ADBAC
		// (set) Token: 0x06001BE9 RID: 7145 RVA: 0x000AF9B4 File Offset: 0x000ADBB4
		public string FileName { get; set; }

		// Token: 0x170003EC RID: 1004
		// (get) Token: 0x06001BEA RID: 7146 RVA: 0x000AF9BD File Offset: 0x000ADBBD
		// (set) Token: 0x06001BEB RID: 7147 RVA: 0x000AF9C5 File Offset: 0x000ADBC5
		public bool DisplayFlipX { get; set; }

		// Token: 0x170003ED RID: 1005
		// (get) Token: 0x06001BEC RID: 7148 RVA: 0x000AF9CE File Offset: 0x000ADBCE
		// (set) Token: 0x06001BED RID: 7149 RVA: 0x000AF9D6 File Offset: 0x000ADBD6
		public bool DisplayFlipY { get; set; }

		// Token: 0x170003EE RID: 1006
		// (get) Token: 0x06001BEE RID: 7150 RVA: 0x000AF9DF File Offset: 0x000ADBDF
		// (set) Token: 0x06001BEF RID: 7151 RVA: 0x000AF9E7 File Offset: 0x000ADBE7
		public float DisplayRotate { get; set; }

		// Token: 0x170003EF RID: 1007
		// (get) Token: 0x06001BF0 RID: 7152 RVA: 0x000AF9F0 File Offset: 0x000ADBF0
		// (set) Token: 0x06001BF1 RID: 7153 RVA: 0x000AF9F8 File Offset: 0x000ADBF8
		public double Precision
		{
			get
			{
				return this.mPrecision;
			}
			set
			{
				this.mPrecision = value;
			}
		}

		// Token: 0x170003F0 RID: 1008
		// (get) Token: 0x06001BF2 RID: 7154 RVA: 0x000AEDC8 File Offset: 0x000ACFC8
		public double MinX
		{
			get
			{
				return this.mBoundingBox.MinX;
			}
		}

		// Token: 0x170003F1 RID: 1009
		// (get) Token: 0x06001BF3 RID: 7155 RVA: 0x000AEDD5 File Offset: 0x000ACFD5
		public double MaxX
		{
			get
			{
				return this.mBoundingBox.MaxX;
			}
		}

		// Token: 0x170003F2 RID: 1010
		// (get) Token: 0x06001BF4 RID: 7156 RVA: 0x000AEDE2 File Offset: 0x000ACFE2
		public double MinY
		{
			get
			{
				return this.mBoundingBox.MinY;
			}
		}

		// Token: 0x170003F3 RID: 1011
		// (get) Token: 0x06001BF5 RID: 7157 RVA: 0x000AEDEF File Offset: 0x000ACFEF
		public double MaxY
		{
			get
			{
				return this.mBoundingBox.MaxY;
			}
		}

		// Token: 0x170003F4 RID: 1012
		// (get) Token: 0x06001BF6 RID: 7158 RVA: 0x000AEDFC File Offset: 0x000ACFFC
		public Rect2D Bounds
		{
			get
			{
				return this.mBoundingBox;
			}
		}

		// Token: 0x170003F5 RID: 1013
		public TriangulationPoint this[int index]
		{
			get
			{
				return this.mPoints[index] as TriangulationPoint;
			}
			set
			{
				this.mPoints[index] = value;
			}
		}

		// Token: 0x170003F6 RID: 1014
		// (get) Token: 0x06001BF9 RID: 7161 RVA: 0x000AFA01 File Offset: 0x000ADC01
		public IList<Polygon> Holes
		{
			get
			{
				return this.mHoles;
			}
		}

		// Token: 0x06001BFA RID: 7162 RVA: 0x000AEE1C File Offset: 0x000AD01C
		IEnumerator<TriangulationPoint> IEnumerable<TriangulationPoint>.GetEnumerator()
		{
			return new TriangulationPointEnumerator(this.mPoints);
		}

		// Token: 0x06001BFB RID: 7163 RVA: 0x000AEE29 File Offset: 0x000AD029
		public int IndexOf(TriangulationPoint p)
		{
			return this.mPoints.IndexOf(p);
		}

		// Token: 0x06001BFC RID: 7164 RVA: 0x000AEE37 File Offset: 0x000AD037
		public override void Add(Point2D p)
		{
			this.Add(p, -1, true);
		}

		// Token: 0x06001BFD RID: 7165 RVA: 0x000AEE37 File Offset: 0x000AD037
		public void Add(TriangulationPoint p)
		{
			this.Add(p, -1, true);
		}

		// Token: 0x06001BFE RID: 7166 RVA: 0x000AEE37 File Offset: 0x000AD037
		public void Add(PolygonPoint p)
		{
			this.Add(p, -1, true);
		}

		// Token: 0x06001BFF RID: 7167 RVA: 0x000AFA0C File Offset: 0x000ADC0C
		protected override void Add(Point2D p, int idx, bool bCalcWindingOrderAndEpsilon)
		{
			TriangulationPoint triangulationPoint = p as TriangulationPoint;
			if (triangulationPoint == null)
			{
				return;
			}
			if (this.mPointMap.ContainsKey(triangulationPoint.VertexCode))
			{
				return;
			}
			this.mPointMap.Add(triangulationPoint.VertexCode, triangulationPoint);
			base.Add(p, idx, bCalcWindingOrderAndEpsilon);
			PolygonPoint polygonPoint = p as PolygonPoint;
			if (polygonPoint != null)
			{
				polygonPoint.Previous = this._last;
				if (this._last != null)
				{
					polygonPoint.Next = this._last.Next;
					this._last.Next = polygonPoint;
				}
				this._last = polygonPoint;
			}
		}

		// Token: 0x06001C00 RID: 7168 RVA: 0x000AFAA4 File Offset: 0x000ADCA4
		public void AddRange(IList<PolygonPoint> points, Point2DList.WindingOrderType windingOrder)
		{
			if (points == null || points.Count < 1)
			{
				return;
			}
			if (this.mWindingOrder == Point2DList.WindingOrderType.Unknown && base.Count == 0)
			{
				this.mWindingOrder = windingOrder;
			}
			int count = points.Count;
			bool flag = base.WindingOrder != Point2DList.WindingOrderType.Unknown && windingOrder != Point2DList.WindingOrderType.Unknown && base.WindingOrder != windingOrder;
			for (int i = 0; i < count; i++)
			{
				int index = i;
				if (flag)
				{
					index = points.Count - i - 1;
				}
				this.Add(points[index], -1, false);
			}
			if (this.mWindingOrder == Point2DList.WindingOrderType.Unknown)
			{
				this.mWindingOrder = base.CalculateWindingOrder();
			}
			this.mEpsilon = base.CalculateEpsilon();
		}

		// Token: 0x06001C01 RID: 7169 RVA: 0x000AFB64 File Offset: 0x000ADD64
		public void AddRange(IList<TriangulationPoint> points, Point2DList.WindingOrderType windingOrder)
		{
			if (points == null || points.Count < 1)
			{
				return;
			}
			if (this.mWindingOrder == Point2DList.WindingOrderType.Unknown && base.Count == 0)
			{
				this.mWindingOrder = windingOrder;
			}
			int count = points.Count;
			bool flag = base.WindingOrder != Point2DList.WindingOrderType.Unknown && windingOrder != Point2DList.WindingOrderType.Unknown && base.WindingOrder != windingOrder;
			for (int i = 0; i < count; i++)
			{
				int index = i;
				if (flag)
				{
					index = points.Count - i - 1;
				}
				this.Add(points[index], -1, false);
			}
			if (this.mWindingOrder == Point2DList.WindingOrderType.Unknown)
			{
				this.mWindingOrder = base.CalculateWindingOrder();
			}
			this.mEpsilon = base.CalculateEpsilon();
		}

		// Token: 0x06001C02 RID: 7170 RVA: 0x000AF0CC File Offset: 0x000AD2CC
		public void Insert(int idx, TriangulationPoint p)
		{
			this.Add(p, idx, true);
		}

		// Token: 0x06001C03 RID: 7171 RVA: 0x000AFC24 File Offset: 0x000ADE24
		public bool Remove(TriangulationPoint p)
		{
			return base.Remove(p);
		}

		// Token: 0x06001C04 RID: 7172 RVA: 0x000AFC30 File Offset: 0x000ADE30
		public void RemovePoint(PolygonPoint p)
		{
			PolygonPoint next = p.Next;
			PolygonPoint previous = p.Previous;
			previous.Next = next;
			next.Previous = previous;
			this.mPoints.Remove(p);
			this.mBoundingBox.Clear();
			foreach (Point2D point2D in this.mPoints)
			{
				PolygonPoint p2 = (PolygonPoint)point2D;
				this.mBoundingBox.AddPoint(p2);
			}
		}

		// Token: 0x06001C05 RID: 7173 RVA: 0x000AF0E0 File Offset: 0x000AD2E0
		public bool Contains(TriangulationPoint p)
		{
			return this.mPoints.Contains(p);
		}

		// Token: 0x06001C06 RID: 7174 RVA: 0x000AFCCC File Offset: 0x000ADECC
		public void CopyTo(TriangulationPoint[] array, int arrayIndex)
		{
			int num = Math.Min(base.Count, array.Length - arrayIndex);
			for (int i = 0; i < num; i++)
			{
				array[arrayIndex + i] = (this.mPoints[i] as TriangulationPoint);
			}
		}

		// Token: 0x06001C07 RID: 7175 RVA: 0x000AFD12 File Offset: 0x000ADF12
		public void AddSteinerPoint(TriangulationPoint point)
		{
			if (this.mSteinerPoints == null)
			{
				this.mSteinerPoints = new List<TriangulationPoint>();
			}
			this.mSteinerPoints.Add(point);
		}

		// Token: 0x06001C08 RID: 7176 RVA: 0x000AFD36 File Offset: 0x000ADF36
		public void AddSteinerPoints(List<TriangulationPoint> points)
		{
			if (this.mSteinerPoints == null)
			{
				this.mSteinerPoints = new List<TriangulationPoint>();
			}
			this.mSteinerPoints.AddRange(points);
		}

		// Token: 0x06001C09 RID: 7177 RVA: 0x000AFD5A File Offset: 0x000ADF5A
		public void ClearSteinerPoints()
		{
			if (this.mSteinerPoints != null)
			{
				this.mSteinerPoints.Clear();
			}
		}

		// Token: 0x06001C0A RID: 7178 RVA: 0x000AFD72 File Offset: 0x000ADF72
		public void AddHole(Polygon poly)
		{
			if (this.mHoles == null)
			{
				this.mHoles = new List<Polygon>();
			}
			this.mHoles.Add(poly);
		}

		// Token: 0x06001C0B RID: 7179 RVA: 0x000AFD96 File Offset: 0x000ADF96
		public void AddTriangle(DelaunayTriangle t)
		{
			this.mTriangles.Add(t);
		}

		// Token: 0x06001C0C RID: 7180 RVA: 0x000AFDA4 File Offset: 0x000ADFA4
		public void AddTriangles(IEnumerable<DelaunayTriangle> list)
		{
			this.mTriangles.AddRange(list);
		}

		// Token: 0x06001C0D RID: 7181 RVA: 0x000AFDB2 File Offset: 0x000ADFB2
		public void ClearTriangles()
		{
			if (this.mTriangles != null)
			{
				this.mTriangles.Clear();
			}
		}

		// Token: 0x06001C0E RID: 7182 RVA: 0x000AFDCA File Offset: 0x000ADFCA
		public bool IsPointInside(TriangulationPoint p)
		{
			return PolygonUtil.PointInPolygon2D(this, p);
		}

		// Token: 0x06001C0F RID: 7183 RVA: 0x000AFDD4 File Offset: 0x000ADFD4
		public void Prepare(TriangulationContext tcx)
		{
			if (this.mTriangles == null)
			{
				this.mTriangles = new List<DelaunayTriangle>(this.mPoints.Count);
			}
			else
			{
				this.mTriangles.Clear();
			}
			for (int i = 0; i < this.mPoints.Count - 1; i++)
			{
				tcx.NewConstraint(this[i], this[i + 1]);
			}
			tcx.NewConstraint(this[0], this[base.Count - 1]);
			tcx.Points.AddRange(this);
			if (this.mHoles != null)
			{
				foreach (Polygon polygon in this.mHoles)
				{
					for (int j = 0; j < polygon.mPoints.Count - 1; j++)
					{
						tcx.NewConstraint(polygon[j], polygon[j + 1]);
					}
					tcx.NewConstraint(polygon[0], polygon[polygon.Count - 1]);
					tcx.Points.AddRange(polygon);
				}
			}
			if (this.mSteinerPoints != null)
			{
				tcx.Points.AddRange(this.mSteinerPoints);
			}
		}

		// Token: 0x04001D67 RID: 7527
		protected Dictionary<uint, TriangulationPoint> mPointMap = new Dictionary<uint, TriangulationPoint>();

		// Token: 0x04001D68 RID: 7528
		protected List<DelaunayTriangle> mTriangles;

		// Token: 0x04001D6D RID: 7533
		private double mPrecision = TriangulationPoint.kVertexCodeDefaultPrecision;

		// Token: 0x04001D6E RID: 7534
		protected List<Polygon> mHoles;

		// Token: 0x04001D6F RID: 7535
		protected List<TriangulationPoint> mSteinerPoints;

		// Token: 0x04001D70 RID: 7536
		protected PolygonPoint _last;
	}
}
